<?php

namespace App\Services;

use App\Models\Post;
use App\Models\Category;
use App\Models\Tag;
use App\Models\Draft;
use App\Models\User;
use App\Events\PostPublished;
use Illuminate\Support\Str;
use Carbon\Carbon;

/**
 * 文章服务类
 * 
 * 职责：
 * - 处理文章相关的业务逻辑
 * - 文章创建、更新、删除的业务规则
 * - Slug生成和唯一性验证
 * - 发布状态管理
 * - 标签关联处理
 */
class PostService extends BaseService
{
    /**
     * 创建新文章
     * 
     * @param array $data 文章数据
     * @param User $user 作者
     * @return Post
     */
    public function create(array $data, User $user): Post
    {
        // 处理摘要：如果前端没有提供或为空，由后端生成
        // 后端生成更安全（会移除HTML标签）
        $excerpt = (!empty($data['excerpt'])) 
            ? trim($data['excerpt']) 
            : $this->generateExcerpt($data['content']);

        // 处理Slug：如果前端没有提供或为空，由后端生成
        // 后端生成会检查数据库唯一性，确保数据一致性
        $slug = $this->generateUniqueSlug($data['slug'] ?? null, $data['title']);

        // 处理系列相关字段
        $seriesId = $data['series_id'] ?? null;
        $seriesOrder = $data['series_order'] ?? null;
        $sortMode = $data['sort_mode'] ?? 'manual';
        
        // 如果指定了 series_id，需要从 Series 获取 sort_mode（如果未提供）
        if ($seriesId && !isset($data['sort_mode'])) {
            $series = \App\Models\Series::find($seriesId);
            if ($series) {
                // 获取系列中第一篇文章的 sort_mode（系列内所有文章的 sort_mode 应该相同）
                $firstPost = \App\Models\Post::where('series_id', $seriesId)->first();
                $sortMode = $firstPost?->sort_mode ?? 'manual';
            }
        }

        // 创建文章
        $post = Post::create([
            'author_id' => $user->id,
            'title' => $data['title'],
            'content' => $data['content'],
            'excerpt' => $excerpt,
            'slug' => $slug,
            'category_id' => $data['category_id'],
            'series_id' => $seriesId,
            'series_order' => $seriesOrder,
            'sort_mode' => $sortMode,
            'status' => $data['status'],
            'featured_image' => $data['featured_image'] ?? null,
            'allow_comments' => $data['settings']['allowComments'] ?? true,
            'featured' => $data['settings']['isFeatured'] ?? false,
            'published_at' => $this->handlePublishDate($data['status'], $data['scheduled_publish_at'] ?? null),
            'scheduled_publish_at' => $data['status'] === 'scheduled' ? $data['scheduled_publish_at'] ?? null : null,
        ]);

        // 如果文章属于系列，更新系列的文章数量
        if ($seriesId) {
            $seriesService = app(\App\Services\SeriesService::class);
            $series = \App\Models\Series::find($seriesId);
            if ($series) {
                $seriesService->updatePostCount($series);
            }
        }

        // 关联标签：处理混合数据（ID 和名称）
        if (!empty($data['tags']) && is_array($data['tags'])) {
            $tagIds = $this->processTags($data['tags']);
            $post->tags()->sync($tagIds);
        }

        // 清除相关草稿
        $this->clearDrafts($user->id, null);

        // 如果文章被发布，触发事件
        if ($post->published_at) {
            event(new PostPublished($post));
        }

        return $post;
    }

    /**
     * 更新文章
     * 
     * @param Post $post 文章模型
     * @param array $data 更新数据
     * @param User|null $user 用户（用于清除草稿，可选）
     * @return Post
     */
    public function update(Post $post, array $data, ?User $user = null): Post
    {
        // 处理摘要：如果内容更新且没有提供摘要，由后端生成
        // 如果提供了摘要但为空字符串，也由后端生成
        if (isset($data['content'])) {
            $data['excerpt'] = (!empty($data['excerpt'])) 
                ? trim($data['excerpt']) 
                : $this->generateExcerpt($data['content']);
        }

        // 处理Slug：如果标题或slug更新，由后端统一处理
        // 后端会检查唯一性并处理中文标题
        if (isset($data['title']) || isset($data['slug'])) {
            $slug = $this->generateUniqueSlug(
                $data['slug'] ?? null,
                $data['title'] ?? $post->title,
                $post->id
            );
            $data['slug'] = $slug;
        }

        // 检查更新前是否已发布
        $wasPublished = $post->published_at !== null;

        // 处理发布状态
        if (isset($data['status'])) {
            $data['published_at'] = $this->handlePublishDate(
                $data['status'],
                $data['scheduled_publish_at'] ?? null,
                $post->published_at
            );
            
            if ($data['status'] !== 'scheduled') {
                $data['scheduled_publish_at'] = null;
            }
        }

        // 处理设置
        if (isset($data['settings'])) {
            $data['allow_comments'] = $data['settings']['allowComments'] ?? $post->allow_comments;
            $data['featured'] = $data['settings']['isFeatured'] ?? $post->featured;
            unset($data['settings']);
        }

        // 处理系列相关字段
        $oldSeriesId = $post->series_id;
        $seriesId = $data['series_id'] ?? $post->series_id;
        
        // 如果更改了 series_id，需要更新 sort_mode
        if (isset($data['series_id']) && $data['series_id'] !== $oldSeriesId) {
            if ($data['series_id']) {
                // 获取系列中第一篇文章的 sort_mode（系列内所有文章的 sort_mode 应该相同）
                $firstPost = Post::where('series_id', $data['series_id'])->first();
                $data['sort_mode'] = $firstPost?->sort_mode ?? 'manual';
            } else {
                // 如果移除了系列，重置 sort_mode
                $data['sort_mode'] = 'manual';
                $data['series_order'] = null;
            }
        }

        // 更新文章
        $post->update($data);

        // 更新系列的文章数量（如果系列发生了变化）
        $seriesService = app(\App\Services\SeriesService::class);
        if ($oldSeriesId !== $seriesId) {
            // 更新旧系列的文章数量
            if ($oldSeriesId) {
                $oldSeries = \App\Models\Series::find($oldSeriesId);
                if ($oldSeries) {
                    $seriesService->updatePostCount($oldSeries);
                }
            }
            // 更新新系列的文章数量
            if ($seriesId) {
                $newSeries = \App\Models\Series::find($seriesId);
                if ($newSeries) {
                    $seriesService->updatePostCount($newSeries);
                }
            }
        } elseif ($seriesId) {
            // 如果系列未变化，也更新文章数量（以防文章状态变化）
            $series = \App\Models\Series::find($seriesId);
            if ($series) {
                $seriesService->updatePostCount($series);
            }
        }

        // 关联标签：处理混合数据（ID 和名称）
        if (isset($data['tags'])) {
            $tagIds = $this->processTags($data['tags'] ?? []);
            $post->tags()->sync($tagIds);
        }

        // 清除相关草稿（如果提供了用户）
        if ($user) {
            $this->clearDrafts($user->id, $post->id);
        }

        // 如果文章被发布（从草稿变为已发布），触发事件
        $post = $post->fresh();
        if ($post->published_at && !$wasPublished) {
            event(new PostPublished($post));
        }

        return $post;
    }

    /**
     * 获取已发布的文章列表
     * 
     * @param array $filters 过滤条件
     * @param int $perPage 每页数量
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getPublishedPosts(array $filters = [], int $perPage = 9)
    {
        $query = Post::with(['author', 'category'])
            ->latestPublished();

        // 搜索过滤
        if (!empty($filters['search'])) {
            $search = $filters['search'];
            $query->where(function($q) use ($search) {
                $q->where('title', 'like', "%{$search}%")
                  ->orWhere('content', 'like', "%{$search}%");
            });
        }

        return $query->paginate($perPage)->withQueryString();
    }

    /**
     * 获取归档数据
     * 
     * @return \Illuminate\Support\Collection
     */
    public function getArchives()
    {
        return Post::with(['author', 'category'])
            ->latestPublished()
            ->get()
            ->groupBy(function($post) {
                return $post->published_at->format('Y');
            })
            ->sortKeysDesc();
    }

    /**
     * 获取文章详情（包含所有关联数据）
     * 
     * @param Post $post 文章模型
     * @param bool $incrementViews 是否增加阅读量
     * @return Post
     */
    public function getPostDetail(Post $post, bool $incrementViews = true): Post
    {
        // 增加阅读量
        if ($incrementViews) {
            $this->incrementViews($post);
        }

        // 加载关联数据
        $post->load([
            'author', 
            'category', 
            'tags',
            'comments' => function($query) {
                $query->whereNull('parent_id')
                      ->with(['user', 'replies.user'])
                      ->orderBy('created_at', 'desc');
            }
        ]);

        // 加载计数
        $post->loadCount('likes');
        $post->is_liked = $post->isLikedBy(auth()->user());

        return $post;
    }

    /**
     * 增加文章阅读量（带缓存防重复计数）
     * 
     * @param Post $post 文章模型
     * @return void
     */
    public function incrementViews(Post $post): void
    {
        // 获取访客标识（使用 session id）
        $visitor = session()->getId();
        
        // 构建缓存键名
        $cacheKey = "post.{$post->id}.views.{$visitor}";
        
        // 检查24小时内是否已经记录过该访客的浏览
        if (!cache()->has($cacheKey)) {
            // 增加阅读量
            $post->incrementViews();
            
            // 记录该访客的浏览，24小时内不再重复计数
            cache()->put($cacheKey, true, now()->addHours(24));
        }
    }

    /**
     * 获取相关文章
     * 
     * @param Post $post 当前文章
     * @param int $limit 返回数量，默认3篇
     * @return \Illuminate\Database\Eloquent\Collection
     */
    public function getRelatedPosts(Post $post, int $limit = 3)
    {
        $query = Post::published()
            ->with(['author', 'category'])
            ->where('id', '!=', $post->id);
        
        // 首先尝试通过标签匹配
        if ($post->tags->isNotEmpty()) {
            $query->whereHas('tags', function($q) use ($post) {
                $q->whereIn('tags.id', $post->tags->pluck('id'));
            });
        } elseif ($post->category_id) {
            // 如果没有标签但有分类，则通过分类匹配
            $query->where('category_id', $post->category_id);
        }
        
        return $query->latestPublished()
                     ->take($limit)
                     ->get();
    }

    /**
     * 获取上一篇和下一篇文章
     * 
     * @param Post $post 当前文章
     * @return array 包含 'prev' 和 'next' 键的数组
     */
    public function getPrevNextPosts(Post $post): array
    {
        return [
            'prev' => Post::published()
                ->where('published_at', '<', $post->published_at)
                ->orderBy('published_at', 'desc')
                ->select('id', 'title', 'slug')
                ->first(),
            'next' => Post::published()
                ->where('published_at', '>', $post->published_at)
                ->orderBy('published_at', 'asc')
                ->select('id', 'title', 'slug')
                ->first(),
        ];
    }

    /**
     * 生成文章摘要
     * 
     * 从 Markdown 内容中提取纯文本摘要，移除所有 Markdown 格式符号
     * 
     * @param string $content 文章内容（Markdown 格式）
     * @return string 纯文本摘要
     */
    protected function generateExcerpt(string $content): string
    {
        // 1. 移除 HTML 标签
        $excerpt = strip_tags($content);
        
        // 2. 移除代码块（```...``` 或 ```language...```）
        // 使用非贪婪匹配，确保匹配最短的代码块
        $excerpt = preg_replace('/```[\s\S]*?```/', '', $excerpt);
        
        // 3. 移除行内代码（`...`），但要避免匹配代码块中的内容
        // 先处理行内代码，避免与代码块冲突
        $excerpt = preg_replace('/`[^`\n]+`/', '', $excerpt);
        
        // 4. 移除图片格式（完全移除，不保留任何内容）
        // 匹配：![alt](url) 或 ![alt](url "title") 或 ![alt](url 'title')
        // 先处理带引号标题的图片
        $excerpt = preg_replace('/!\[[^\]]*\]\s*\([^\)]*\s+["\'][^\'"]*["\']\s*\)/', '', $excerpt);
        // 再处理不带标题的图片
        $excerpt = preg_replace('/!\[[^\]]*\]\s*\([^\)]*\)/', '', $excerpt);
        // 处理空的图片语法
        $excerpt = preg_replace('/!\[\]\s*\([^\)]*\)/', '', $excerpt);
        
        // 5. 移除链接格式（完全移除，不保留任何内容）
        // 注意：图片已经处理过了，这里只处理普通链接
        $excerpt = preg_replace('/\[[^\]]+\]\([^\)]+\)/', '', $excerpt); // [text](url) -> 完全移除
        $excerpt = preg_replace('/\[[^\]]+\]\[[^\]]+\]/', '', $excerpt); // [text][ref] -> 完全移除
        
        // 6. 移除标题符号（# ## ### 等）
        $excerpt = preg_replace('/^#{1,6}\s+/m', '', $excerpt);
        
        // 7. 移除引用符号（>）
        $excerpt = preg_replace('/^>\s+/m', '', $excerpt);
        
        // 8. 移除任务列表标记（- [x] 或 - [ ]）
        $excerpt = preg_replace('/^[\s]*[-*+]\s+\[[x\s]\]\s+/m', '', $excerpt);
        
        // 9. 移除列表符号（- * + 以及数字列表）
        $excerpt = preg_replace('/^[\s]*[-*+]\s+/m', '', $excerpt);
        $excerpt = preg_replace('/^[\s]*\d+\.\s+/m', '', $excerpt);
        
        // 10. 移除粗体和斜体符号（**text** *text* __text__ _text_）
        // 注意顺序：先处理 **，再处理 *，避免冲突
        $excerpt = preg_replace('/\*\*([^*]+)\*\*/', '$1', $excerpt); // **text** -> text
        $excerpt = preg_replace('/__([^_]+)__/', '$1', $excerpt); // __text__ -> text
        $excerpt = preg_replace('/\*([^*\s][^*]*[^*\s])\*/', '$1', $excerpt); // *text* -> text (避免匹配列表符号)
        $excerpt = preg_replace('/_([^_\s][^_]*[^_\s])_/', '$1', $excerpt); // _text_ -> text
        
        // 11. 移除删除线符号（~~text~~）
        $excerpt = preg_replace('/~~([^~]+)~~/', '$1', $excerpt);
        
        // 12. 移除水平线（--- 或 ***）
        $excerpt = preg_replace('/^[-*]{3,}$/m', '', $excerpt);
        
        // 13. 移除表格符号（|）
        $excerpt = preg_replace('/\|/', ' ', $excerpt);
        
        // 14. 移除脚注引用（[^1] 或 [^note]）
        $excerpt = preg_replace('/\[\^[^\]]+\]/', '', $excerpt);
        
        // 15. 移除多余的空白字符（包括换行符）
        $excerpt = preg_replace('/\s+/', ' ', $excerpt);
        
        // 16. 移除首尾空白并限制长度
        $excerpt = trim($excerpt);
        
        // 17. 如果清理后为空，返回默认文本
        if (empty($excerpt)) {
            $excerpt = '暂无摘要';
        }
        
        return Str::limit($excerpt, 200);
    }

    /**
     * 获取作者的文章列表
     * 
     * @param array $filters 过滤条件（search, status, sort）
     * @param User $user 作者
     * @param int $perPage 每页数量
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getAuthorPosts(array $filters, User $user, int $perPage = 10)
    {
        $query = Post::authoredBy($user)
            ->with(['category', 'tags'])
            ->withCount(['comments', 'likes']);

        // 处理搜索
        if (!empty($filters['search'])) {
            $search = $filters['search'];
            $query->where('title', 'like', "%{$search}%");
        }

        // 处理状态筛选
        if (!empty($filters['status'])) {
            if ($filters['status'] === 'published') {
                $query->whereNotNull('published_at');
            } elseif ($filters['status'] === 'draft') {
                $query->whereNull('published_at');
            }
        }

        // 处理排序
        if (!empty($filters['sort'])) {
            [$field, $direction] = explode(',', $filters['sort']);
            $direction = in_array($direction, ['asc', 'desc']) ? $direction : 'desc';
            
            switch ($field) {
                case 'title':
                case 'published_at':
                case 'created_at':
                case 'views':
                    $query->orderBy($field, $direction);
                    break;
                default:
                    $query->latest('created_at');
                    break;
            }
        } else {
            $query->latest('created_at');
        }

        return $query->paginate($perPage)->withQueryString();
    }

    /**
     * 获取作者文章统计信息
     * 
     * @param User $user 作者
     * @return array
     */
    public function getAuthorStats(User $user): array
    {
        $posts = Post::authoredBy($user)
            ->withCount(['comments', 'likes'])
            ->get();
        
        return [
            'total' => $posts->count(),
            'published' => $posts->whereNotNull('published_at')->count(),
            'draft' => $posts->whereNull('published_at')->count(),
            'total_views' => $posts->sum('views'),
            'total_comments' => $posts->sum('comments_count'),
            'total_likes' => $posts->sum('likes_count'),
        ];
    }

    /**
     * 批量删除文章
     * 
     * @param array $postIds 文章ID数组
     * @param User $user 用户（用于权限检查）
     * @return int 删除数量
     */
    public function batchDelete(array $postIds, User $user): int
    {
        $posts = Post::authoredBy($user)
            ->whereIn('id', $postIds)
            ->get();
        
        $count = 0;
        foreach ($posts as $post) {
            $this->delete($post, $user);
            $count++;
        }
        
        return $count;
    }

    /**
     * 批量更新文章状态
     * 
     * @param array $postIds 文章ID数组
     * @param string $status 新状态
     * @param User $user 用户（用于权限检查）
     * @return int 更新数量
     */
    public function batchUpdateStatus(array $postIds, string $status, User $user): int
    {
        $posts = Post::authoredBy($user)
            ->whereIn('id', $postIds)
            ->get();
        
        $updateData = [];
        
        if ($status === 'published') {
            $updateData['published_at'] = now();
            $updateData['scheduled_publish_at'] = null;
        } elseif ($status === 'draft') {
            $updateData['published_at'] = null;
            $updateData['scheduled_publish_at'] = null;
        }
        
        if (empty($updateData)) {
            return 0;
        }
        
        $count = 0;
        foreach ($posts as $post) {
            $post->update($updateData);
            $count++;
        }
        
        return $count;
    }

    /**
     * 删除文章
     * 
     * @param Post $post 文章模型
     * @param User $user 用户（用于权限检查）
     * @return bool
     * @throws \App\Exceptions\BusinessException
     */
    public function delete(Post $post, User $user): bool
    {
        // 权限检查：只有作者本人可以删除
        if ($post->author_id !== $user->id) {
            $this->throwException('您没有删除此文章的权限', 403);
        }

        return $post->delete();
    }

    /**
     * 从版本恢复文章
     * 
     * @param Post $post 文章模型
     * @param \App\Models\PostRevision $revision 版本模型
     * @param User $user 用户（用于权限检查）
     * @return Post
     * @throws \App\Exceptions\BusinessException
     */
    public function restoreFromRevision(Post $post, \App\Models\PostRevision $revision, User $user): Post
    {
        // 权限检查
        if ($post->author_id !== $user->id && !$user->can('manage posts')) {
            $this->throwException('您没有编辑此文章的权限', 403);
        }

        // 验证版本是否属于该文章
        if ($revision->post_id !== $post->id) {
            $this->throwException('该修订版本不属于此文章', 404);
        }

        // 调用模型的恢复方法
        $post->restoreFromRevision($revision);

        return $post->fresh();
    }

    /**
     * 生成唯一的Slug
     * 
     * @param string|null $slug 指定的slug
     * @param string $title 文章标题
     * @param int|null $excludeId 排除的文章ID（更新时使用）
     * @return string
     */
    protected function generateUniqueSlug(?string $slug, string $title, ?int $excludeId = null): string
    {
        // 如果提供了slug且不为空，验证其唯一性
        if (!empty($slug)) {
            $query = Post::where('slug', $slug);
            if ($excludeId) {
                $query->where('id', '!=', $excludeId);
            }
            if (!$query->exists()) {
                return $slug;
            }
        }

        // 从标题生成slug
        $baseSlug = Str::slug($title);
        
        // 处理中文标题
        if (empty($baseSlug)) {
            $baseSlug = 'post-' . now()->format('YmdHis');
        }

        // 确保唯一性
        $slug = $baseSlug;
        $count = 1;
        $query = Post::where('slug', $slug);
        if ($excludeId) {
            $query->where('id', '!=', $excludeId);
        }

        while ($query->exists()) {
            $slug = $baseSlug . '-' . $count++;
            $query = Post::where('slug', $slug);
            if ($excludeId) {
                $query->where('id', '!=', $excludeId);
            }
        }

        return $slug;
    }

    /**
     * 处理发布日期
     * 
     * @param string $status 文章状态
     * @param string|null $scheduledDate 定时发布日期
     * @param string|null $currentPublishedAt 当前发布日期
     * @return \Carbon\Carbon|null
     */
    protected function handlePublishDate(string $status, ?string $scheduledDate = null, ?string $currentPublishedAt = null): ?Carbon
    {
        if ($status === 'published') {
            // 如果已发布过，保持原日期；否则设为当前时间
            return $currentPublishedAt ? Carbon::parse($currentPublishedAt) : now();
        }

        if ($status === 'scheduled' && $scheduledDate) {
            return null; // 定时发布时不立即设置published_at
        }

        return null; // 草稿状态
    }

    /**
     * 处理标签数据：将混合的标签数据（ID 和名称）转换为标签 ID 数组
     * 
     * @param array $tags 标签数据，可能包含 ID（整数）或名称（字符串）
     * @return array 标签 ID 数组
     */
    protected function processTags(array $tags): array
    {
        if (empty($tags)) {
            return [];
        }

        $tagIds = [];
        $tagNames = [];

        // 分离 ID 和名称
        foreach ($tags as $tag) {
            if (is_numeric($tag)) {
                // 如果是数字，当作 ID 处理
                $tagIds[] = (int) $tag;
            } elseif (is_string($tag) && !empty(trim($tag))) {
                // 如果是字符串，当作标签名称处理
                $tagNames[] = trim($tag);
            }
        }

        // 对于名称，使用 TagService 创建或获取标签
        if (!empty($tagNames)) {
            $tagService = app(TagService::class);
            $createdTags = $tagService->createOrGetMany($tagNames);
            foreach ($createdTags as $tag) {
                $tagIds[] = $tag->id;
            }
        }

        // 去重并返回
        return array_unique($tagIds);
    }

    /**
     * 清除相关草稿
     * 
     * @param int $userId 用户ID
     * @param int|null $postId 文章ID
     * @return void
     */
    protected function clearDrafts(int $userId, ?int $postId = null): void
    {
        $query = Draft::where('user_id', $userId);
        
        if ($postId) {
            $query->where('post_id', $postId);
        } else {
            $query->whereNull('post_id');
        }
        
        $query->delete();
    }

    /**
     * 获取仪表盘统计数据
     * 
     * @return array
     */
    public function getDashboardStats(): array
    {
        return [
            'total_posts' => Post::count(),
            'published_posts' => Post::whereNotNull('published_at')->count(),
            'draft_posts' => Post::whereNull('published_at')->count(),
            'total_views' => Post::sum('views'),
        ];
    }

    /**
     * 获取发布趋势数据（最近30天）
     * 
     * @return \Illuminate\Support\Collection
     */
    public function getPublishTrend(int $days = 30): \Illuminate\Support\Collection
    {
        return Post::whereNotNull('published_at')
            ->where('published_at', '>=', Carbon::now()->subDays($days))
            ->selectRaw('DATE(published_at) as date, COUNT(*) as count')
            ->groupBy('date')
            ->orderBy('date')
            ->get()
            ->map(fn ($item) => [
                'date' => Carbon::parse($item->date)->format('m-d'),
                'count' => (int) $item->count
            ]);
    }

    /**
     * 获取最近文章
     * 
     * @param int $limit 返回数量
     * @return \Illuminate\Support\Collection
     */
    public function getRecentPosts(int $limit = 5): \Illuminate\Support\Collection
    {
        return Post::with(['author', 'category'])
            ->latest('published_at')
            ->limit($limit)
            ->get()
            ->map(fn ($post) => [
                'id' => $post->id,
                'title' => $post->title,
                'author' => $post->author->name,
                'category' => $post->category?->name,
                'published_at' => $post->published_at ? Carbon::parse($post->published_at)->diffForHumans() : null,
                'status' => $post->published_at ? 'published' : 'draft'
            ]);
    }

    /**
     * 获取热门文章
     * 
     * @param int $limit 返回数量
     * @return \Illuminate\Support\Collection
     */
    public function getPopularPosts(int $limit = 5): \Illuminate\Support\Collection
    {
        return Post::with(['author', 'category'])
            ->whereNotNull('published_at')
            ->withCount('likes')
            ->orderByDesc('views')
            ->limit($limit)
            ->get()
            ->map(fn ($post) => [
                'id' => $post->id,
                'title' => $post->title,
                'views' => $post->views,
                'likes' => $post->likes_count,
                'author' => $post->author->name,
                'category' => $post->category?->name
            ]);
    }

    /**
     * 获取管理端文章列表
     * 
     * @param array $filters 过滤条件
     * @param int $perPage 每页数量
     * @return \Illuminate\Contracts\Pagination\LengthAwarePaginator
     */
    public function getAdminPosts(array $filters = [], int $perPage = 10): \Illuminate\Contracts\Pagination\LengthAwarePaginator
    {
        $query = Post::with(['author', 'category', 'tags'])
            ->withCount(['comments', 'likes']);

        // 应用过滤条件（使用模型的 filter scope）
        if (!empty($filters)) {
            $query->filter($filters);
        }

        // 处理排序
        if (!empty($filters['sort'])) {
            [$field, $direction] = explode(',', $filters['sort']);
            $direction = in_array($direction, ['asc', 'desc']) ? $direction : 'desc';
            
            switch ($field) {
                case 'title':
                case 'published_at':
                case 'created_at':
                case 'views':
                    $query->orderBy($field, $direction);
                    break;
                case 'likes_count':
                    $query->orderBy('likes_count', $direction);
                    break;
                case 'comments_count':
                    $query->orderBy('comments_count', $direction);
                    break;
                case 'author':
                    $query->join('users', 'posts.author_id', '=', 'users.id')
                        ->orderBy('users.name', $direction)
                        ->select('posts.*');
                    break;
                case 'category':
                    $query->leftJoin('categories', 'posts.category_id', '=', 'categories.id')
                        ->orderBy('categories.name', $direction)
                        ->select('posts.*');
                    break;
                default:
                    $query->latest('published_at');
                    break;
            }
        } else {
            $query->latest('published_at');
        }

        return $query->paginate($perPage)->withQueryString();
    }

    /**
     * 获取管理端文章详情
     * 
     * @param Post $post 文章模型
     * @return array
     */
    public function getAdminPostDetail(Post $post): array
    {
        $post->load(['author', 'category', 'tags', 'comments.user']);

        return [
            'id' => $post->id,
            'slug' => $post->slug,
            'title' => $post->title,
            'content' => $post->content,
            'excerpt' => $post->excerpt,
            'status' => $post->published_at ? 'published' : 'draft',
            'status_text' => $post->published_at ? '已发布' : '草稿',
            'views' => $post->views,
            'likes_count' => $post->likes()->count(),
            'comments_count' => $post->comments()->count(),
            'created_at' => [
                'formatted' => Carbon::parse($post->created_at)->format('Y年m月d日 H:i'),
            ],
            'published_at' => $post->published_at ? [
                'formatted' => Carbon::parse($post->published_at)->format('Y年m月d日 H:i'),
            ] : null,
            'author' => [
                'name' => $post->author->name,
                'avatar' => $post->author->profile_photo_url,
            ],
            'category' => $post->category ? [
                'name' => $post->category->name,
                'slug' => $post->category->slug,
            ] : null,
            'tags' => $post->tags->map(fn($tag) => [
                'id' => $tag->id,
                'name' => $tag->name,
            ]),
            'comments' => $post->comments->map(fn($comment) => [
                'id' => $comment->id,
                'content' => $comment->content,
                'created_at' => [
                    'formatted' => Carbon::parse($comment->created_at)->format('Y年m月d日 H:i'),
                ],
                'user' => [
                    'name' => $comment->user->name,
                    'avatar' => $comment->user->profile_photo_url,
                ],
            ]),
        ];
    }

    /**
     * 复制文章
     * 
     * @param Post $post 原文章
     * @return Post
     */
    public function duplicate(Post $post): Post
    {
        $newPost = $post->replicate();
        $newPost->title = $post->title . ' (副本)';
        $newPost->slug = $this->generateUniqueSlug(null, $newPost->title);
        $newPost->published_at = null;
        $newPost->scheduled_publish_at = null;
        $newPost->save();

        // 复制标签关联
        $newPost->tags()->attach($post->tags->pluck('id'));

        return $newPost;
    }

    /**
     * 切换文章发布状态
     * 
     * @param Post $post 文章模型
     * @return Post
     */
    public function toggleStatus(Post $post): Post
    {
        if ($post->published_at) {
            $post->update([
                'published_at' => null,
                'scheduled_publish_at' => null,
            ]);
        } else {
            $post->update([
                'published_at' => now(),
                'scheduled_publish_at' => null,
            ]);
        }

        return $post->fresh();
    }

    /**
     * 获取同系列文章
     * 
     * @param Post $post 文章模型
     * @return \Illuminate\Support\Collection
     */
    public function getSeriesPosts(Post $post): \Illuminate\Support\Collection
    {
        if (!$post->series_id) {
            return collect([]);
        }

        $seriesService = app(\App\Services\SeriesService::class);
        $series = \App\Models\Series::find($post->series_id);
        
        if (!$series) {
            return collect([]);
        }

        return $seriesService->getPosts($series);
    }

    /**
     * 更新文章在系列中的顺序
     * 
     * @param Post $post 文章模型
     * @param int $newOrder 新顺序
     * @return bool
     */
    public function updateSeriesOrder(Post $post, int $newOrder): bool
    {
        if (!$post->series_id) {
            $this->throwException('文章不属于任何系列', 400);
        }

        // 验证 sort_mode 是否为 manual
        if ($post->sort_mode !== 'manual') {
            $this->throwException('只有手动排序模式才能更新顺序', 400);
        }

        $post->update(['series_order' => $newOrder]);

        // 更新系列的文章数量
        $seriesService = app(\App\Services\SeriesService::class);
        $series = \App\Models\Series::find($post->series_id);
        if ($series) {
            $seriesService->updatePostCount($series);
        }

        return true;
    }

    /**
     * 获取系列内上一篇文章
     * 
     * @param Post $post 文章模型
     * @return Post|null
     */
    public function getPreviousPost(Post $post): ?Post
    {
        return $post->previousInSeries();
    }

    /**
     * 获取系列内下一篇文章
     * 
     * @param Post $post 文章模型
     * @return Post|null
     */
    public function getNextPost(Post $post): ?Post
    {
        return $post->nextInSeries();
    }
}

